package com.peach.filter;

import com.peach.domain.ResultVO;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
public class ControllerInterceptor {

    /**
     * 定义拦截规则：拦截com.xjj.web.controller包下面的所有类中，有@RequestMapping注解的方法。
     * Pointcut 需要定义一个空的方法，然后 再用 around before after 等注解 在切入点的前、后、前和后织入逻辑，然后around before after 下面的方法用来填充空的方法 实际执行的逻辑是around before after 下面的方法。
     */
    @Pointcut("execution(* com.peach.controller..*(..)) && @annotation(org.springframework.web.bind.annotation" +
            ".RequestMapping)")
    public void controllerMethodPointcut(){};

    @Around("controllerMethodPointcut()")
    /**登录验证拦截方法
     * @parameter pjp 拦截进来的方法;
     * @return Object 返还接口方法 让其继续执行  或者返还报错类型。
     */
    public Object loginInterceptor (ProceedingJoinPoint pjp){
        try {
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            //被拦截的接口
            Method method = signature.getMethod();
            //被拦截的接口名
            String methodName = method.getName();
            //返还的方式
            Object result = null;
            System.out.println("当前运行的方法为："+methodName);
            //TODO:排除注册接口……后续想到再继续添加
            switch (methodName){
                case "register":
                    System.out.println("无须登录");
                    return pjp.proceed();
                case "userLogin":
                    System.out.println("无须登录");
                    return pjp.proceed();
                case "managerLogin":
                    System.out.println("无须登录");
                    return pjp.proceed();
                case "doPut":
                    System.out.println("无须登录");
                    return pjp.proceed();
                case "logout":
                    System.out.println("无须登录");
                    return pjp.proceed();
                case "modifyPassword":
                    System.out.println("无须登录");
                    return pjp.proceed();
                case "test":
                    System.out.println("无须登录");
                    return pjp.proceed();
                default:
                    break;
            }

            //该接口的参数
            Object[] paras = pjp.getArgs();
            //准备转换后的参数
            HttpServletRequest req = null;
            HttpServletResponse res = null;
            Map map = null;
            //转换参数
            for (Object arg: paras
                 ) {
                if (arg instanceof Map<?,?>){
                    map = new HashMap();
                }else if (arg instanceof HttpServletRequest){
                    req = (HttpServletRequest) arg;
                }else if (arg instanceof HttpServletResponse){
                    res = (HttpServletResponse) arg;
                }
            }

            //如果成功接收参数
            if (req != null){
                Boolean isLogin = (Boolean)req.getSession().getAttribute("isLogin");
                System.out.println("用户登录状态："+isLogin);
                if (isLogin != null && isLogin){
                    result = pjp.proceed();
                }else {
                    result = new ResultVO(false,null,"用户未登录，请登录");
                }
            }else {
                result = new ResultVO(false,null,"用户未登录，请登录");
            }
            //返回拦截进来的方法 让方法继续执行
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            return new ResultVO(false,null,"发生异常："+throwable.getMessage());
        }
    }
}
